#ifndef MATH_MATRIX_H
#define MATH_MATRIX_H

/*
Matrix setup
| vec1 |
| vec2 |
| vec3 |

*/

template< typename T, unsigned int R, unsigned int C >
class Matrix {
  public:
    Matrix();
    Matrix( T* vals );
    Matrix& operator()( T* vals );

    template< unsigned int X, unsigned int Y > 
    Matrix( const Matrix<T,X,Y>& matrix );

    Matrix<T,R,C+1> AddColumn( unsigned int target, const Vector<T,R>& val = Vector<T,R>() ) const;
    Matrix<T,R,C-1> RemoveColumn( unsigned int target ) const;

    Matrix<T,R+1,C> AddRow( unsigned int target, const Vector<T,C>& val = Vector<T,C>() ) const;
    Matrix<T,R-1,C> RemoveRow( unsigned int target ) const;

    Matrix<T,C,R> Transpose() const;

    bool operator==( const Matrix<T,R,C>& compare ) const;
    bool operator!=( const Matrix<T,R,C>& compare ) const;
    bool IsNull() const;

    inline Vector<T,C>& operator[]( unsigned int target );
    inline Vector<T,C>  operator[]( unsigned int target ) const;

  private:
    Vector<T,C> elems[R];
};

template< typename T, unsigned int R, unsigned int C >
Matrix<T,R,C> operator-( Matrix<T,R,C>& a);

template< typename T, unsigned int N >
T Determinant( Matrix<T,N,N>& a);

#endif
